package main

import (
    "bytes"
    "encoding/base64"
    "encoding/json"
    "fmt"
    "image/png"
    "io"
    "log"
    "math"
    "math/rand"
    "net/http"
    "os"
    "time"
    "github.com/kbinani/screenshot"
    "github.com/lxn/win"
)

// TIP <p>To run your code, right-click the code and select <b>Run</b>.</p> <p>Alternatively, click
// the <icon src="AllIcons.Actions.Execute"/> icon in the gutter and select the <b>Run</b> menu item from here.</p>

// 定义请求体的结构
type RequestData struct {
    Base64Image string `json:"base64_image"`
}

// 定义响应体的结构
type ResponseData struct {
    SomImageBase64    string          `json:"som_image_base64"`
    ParsedContentList []ParsedContent `json:"parsed_content_list"`
    Latency           float64         `json:"latency"`
}

// 定义响应体中ParsedContentList字段的子结构
type ParsedContent struct {
    Type          string    `json:"type"`
    Bbox          []float64 `json:"bbox"`
    Interactivity bool      `json:"interactivity"`
    Content       string    `json:"content"`
    Source        string    `json:"source"`
}

// 发送POST请求的函数
func sendPostRequest(apiURL string, base64Image string) (*ResponseData, error) {
    // 创建请求体
    requestData := RequestData{
        Base64Image: base64Image,
    }

    // 将请求体转换为JSON
    jsonData, err := json.Marshal(requestData)
    if err != nil {
        return nil, fmt.Errorf("无法将请求体转换为JSON: %v", err)
    }

    // 创建HTTP请求
    req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(jsonData))
    if err != nil {
        return nil, fmt.Errorf("无法创建HTTP请求: %v", err)
    }

    // 设置请求头
    req.Header.Set("Content-Type", "application/json")

    // 发送HTTP请求
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return nil, fmt.Errorf("无法发送HTTP请求: %v", err)
    }
    defer resp.Body.Close()

    // 检查响应状态码
    if resp.StatusCode != http.StatusOK {
        return nil, fmt.Errorf("HTTP请求失败，状态码: %d", resp.StatusCode)
    }

    // 输出成功信息
    // 读取响应体
    bodyBytes, err := io.ReadAll(resp.Body)
    if err != nil {
        return nil, fmt.Errorf("无法读取响应体: %v", err)
    }

    // 解析响应体中的JSON数据
    var responseData ResponseData
    err = json.Unmarshal(bodyBytes, &responseData)
    if err != nil {
        return nil, fmt.Errorf("无法解析响应体: %v", err)
    }

    // 解码Base64图片数据
    imageData, err := base64.StdEncoding.DecodeString(responseData.SomImageBase64)
    if err != nil {
        return nil, fmt.Errorf("无法解码Base64图片数据: %v", err)
    }

    // 生成随机文件名
    rand.NewSource(time.Now().UnixNano())
    fileName := fmt.Sprintf("./img/image_%d.png", rand.Intn(10000))

    // 保存图片文件
    err = os.WriteFile(fileName, imageData, 0644)
    if err != nil {
        return nil, fmt.Errorf("无法保存图片文件: %v", err)
    }

    // 输出成功信息
    fmt.Printf("图片已保存为: %s\n", fileName)
    // fmt.Println("解析结果:", (responseData.ParsedContentList))

    return &responseData, nil
}

func main() {
    // img := openImg()

    img, screen_resoultion, _ := get_screenhot()
    // println(img)

    if img == "" {
        println("截图失败")
        return
    }

    // 定义API URL
    apiURL := "http://192.168.1.100:34569/parse/"
    // 调用发送POST请求的函数
    omni_res, err := sendPostRequest(apiURL, img)
    if err != nil {
        fmt.Printf("发送POST请求时出错: %v\n", err)
    }

    fmt.Println("resoultion:", screen_resoultion)

    for i := range omni_res.ParsedContentList {
        for j := range omni_res.ParsedContentList[i].Bbox {
            if (j+1)%2 == 0 {
                // screen height
                omni_res.ParsedContentList[i].Bbox[j] = math.Round(omni_res.ParsedContentList[i].Bbox[j] * float64(screen_resoultion.Height))
            } else {
                // screen width
                omni_res.ParsedContentList[i].Bbox[j] = math.Round(omni_res.ParsedContentList[i].Bbox[j] * float64(screen_resoultion.Width))
            }
        }
    }
    // println("解析结果:", (omni_res.ParsedContentList))
    fmt.Printf("%v+\n", omni_res.ParsedContentList)
    // 移动到第一个元素的中心
    fmt.Println("first x,y:", omni_res.ParsedContentList[0].Bbox[0], omni_res.ParsedContentList[0].Bbox[1])
    fmt.Println("first x,y:", omni_res.ParsedContentList[0])
    moveMouse(int(omni_res.ParsedContentList[0].Bbox[0]), int(omni_res.ParsedContentList[0].Bbox[1]))
}

type Resolution struct {
    Width  int
    Height int
}

func get_screenhot() (string, Resolution, error) {

    display_num := 0
    bounds := screenshot.GetDisplayBounds(display_num)

    r := Resolution{
        Width:  bounds.Dx(),
        Height: bounds.Dy(),
    }

    // 默认采集第一个显示器
    img, err := screenshot.CaptureDisplay(display_num)

    if err != nil {
        fmt.Printf("无法截取屏幕: %v\n", err)
        return "", r, err
    }

    // 创建一个Buffer来存储PNG数据
    var buf bytes.Buffer

    // 将截图编码为PNG格式并写入Buffer
    err = png.Encode(&buf, img)
    if err != nil {
        return "", r, fmt.Errorf("无法编码PNG: %v", err)
    }

    // 将PNG数据转换为Base64字符串
    base64Str := base64.StdEncoding.EncodeToString(buf.Bytes())
    return base64Str, r, nil

    // // 获取所有显示器的数量
    // n := screenshot.NumActiveDisplays()
    //
    // // 遍历所有显示器
    // for i := 0; i < n; i++ {
    //     // 获取指定显示器的边界
    //     bounds := screenshot.GetDisplayBounds(i)
    //
    //     // 截取指定显示器的屏幕
    //     img, err := screenshot.CaptureRect(bounds)
    //
    //     if err != nil {
    //         fmt.Printf("无法截取屏幕: %v\n", err)
    //         return "", err
    //     }
    //
    //     // 创建一个Buffer来存储PNG数据
    //     var buf bytes.Buffer
    //
    //     // 将截图编码为PNG格式并写入Buffer
    //     err = png.Encode(&buf, img)
    //     if err != nil {
    //         return "", fmt.Errorf("无法编码PNG: %v", err)
    //     }
    //
    //     // 将PNG数据转换为Base64字符串
    //     base64Str := base64.StdEncoding.EncodeToString(buf.Bytes())
    //     return base64Str, nil
    // }

    // return "", r, nil
}

func openImg() string {
    // 定义图片的路径
    imgPath := "./img/004.png"

    // 读取图片文件
    file, err := os.Open(imgPath)
    if err != nil {
        log.Fatalf("无法打开文件: %v", err)
    }
    defer file.Close()

    // 读取文件内容
    imgBytes, err := io.ReadAll(file)
    if err != nil {
        log.Fatalf("无法读取文件: %v", err)
    }

    // 将图片内容转换为Base64编码
    base64Str := base64.StdEncoding.EncodeToString(imgBytes)

    // 输出Base64编码的字符串
    return base64Str
}

func moveMouse(x, y int) {
    win.SetCursorPos(int32(x), int32(y))
}

func test_mouse_move() {
    // 获取屏幕的尺寸
    screenWidth := win.GetSystemMetrics(win.SM_CXSCREEN)
    screenHeight := win.GetSystemMetrics(win.SM_CYSCREEN)

    // 计算目标位置
    targetX := screenWidth / 2
    targetY := screenHeight / 2

    fmt.Printf("将鼠标移动到屏幕中心: (%d, %d)\n", targetX, targetY)

    // 模拟鼠标移动
    moveMouse(int(targetX), int(targetY))

    // 等待2秒以观察效果
    time.Sleep(2 * time.Second)
}
